<!-- 
未完成功能：
1. 合并表头
2. 最后一列审计结果需要插入template,radio √
3. 确保其他单元格的合并范围不会超出当前单元格的合并范围 169行表的问题,暂时可以写死  √
4. 获取接口数据 



1.最后一行加input或结果 √
2.transformLast应该计算取最后一个，并不是fileds7
-->
<template>
  <el-table :data="tableData" style="width: 100%" border :span-method="mergerRule">
    <!-- todo -- 合并表头 -->
    <el-table-column v-for="(item, i) in tableColumn" :prop="item.prop" :label="item.label" :key="i">
      <template #default="{ row, column, $index }">
        <span v-if="item.prop != `fields${tableColumn.length}`">{{ row[column.property] }}</span>
        <div v-if="item.prop == `fields${tableColumn.length}`">
          <el-radio-group v-if="row[`fields${tableColumn.length}`].change.length"
            v-model="row[`fields${tableColumn.length}`].result" :value-key="row.rid">
            <el-radio :value="nwl.value" :label="nwl.value" v-for="nwl in row[`fields${tableColumn.length}`].change">{{
    nwl.label }}</el-radio>
          </el-radio-group>
          <div v-if="row[`fields${tableColumn.length}`].result == '1'">
            <span>若是，具体内容：</span>
            <el-input v-model="row[`fields${tableColumn.length}`].content" style="width: 240px" placeholder="请输入" />
          </div>
        </div>
      </template>
    </el-table-column>
  </el-table>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import * as XLSX from 'xlsx'; //解析Excel

const tableData = ref<any[]>([]); // 表格数据
const excelData = ref([] as any[]); // Excel 数据
const tableColumn = ref([] as { prop: string; label: any; }[]); // 表头
//转换最后一列
const transformLast = (str) => {
  const id = parseInt(str.match(/\d+/)[0], 10);
  const remainingStr = str.replace(/\d+/g, '');
  const labels = remainingStr.split('、');
  const change = labels == '' ? [] : labels.map((label, index) => ({ value: index, label }));
  const result = 0
  const content = '';
  return { id, change, result, content };
};
//加载Excel
const loadExcel = async () => {
  const response = await fetch('/test.xlsx'); //加载Excel文件，以后换成接口返回的excel文件地址
  const blob = await response.blob();
  const reader = new FileReader();
  //读取文件
  reader.onload = (e) => {
    //解析Excel
    const data = new Uint8Array(e.target.result);
    const workbook = XLSX.read(data, { type: 'array' });
    const firstSheetName = workbook.SheetNames[0]; //获取第一个表名
    const worksheet = workbook.Sheets[firstSheetName]; //获取第一个表
    /* 
    转成json格式
    header: 1 表示第一行是表头
    defval: null 表示空值用null代替  **必加,否则解析出来的array.length对应不上**
     */
    excelData.value = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: null });
    console.log('Excel data:', excelData.value);
    //抽取表头
    tableColumn.value = convertToTableColumn(excelData.value[0]).slice(0, -2);
    //转换表格数据
    tableData.value = convertTableData(excelData.value.slice(1)).map(item => {
      //去掉最后两列
        const keys = Object.keys(item);
        const newItem = {};
        keys.slice(0, -2).forEach(key => {
          newItem[key] = item[key];
        });
        return newItem;
      }).map(item => {
        //转换最后一列
        const keys = Object.keys(item);
      if (item[`fields${tableColumn.value.length}`]) {
        item[`fields${tableColumn.value.length}`] = transformLast(item[`fields${tableColumn.value.length}`]);
      }
      return item;
    });;
    console.log('Table data:', tableData.value);
    console.log('Table column:', tableColumn.value);
  };
  reader.readAsArrayBuffer(blob);
}

//抽取表头
const convertToTableColumn = (arr: any[]) => {
  return arr.map((item, index) => {
    return {
      prop: `fields${index + 1}`,
      label: item === null ? null : item
    };
  });
};
//转换表格数据
const convertTableData = (arr: any[]) => {
  return arr.map((item, index) => {
    const obj: any = {};
    item.forEach((cell: any, cellIndex: number) => {
      obj[`fields${cellIndex + 1}`] = cell;
    });
    return obj;
  });
};

//合并规则
const mergerRule = ({ row, column, rowIndex, columnIndex }: { row: any, column: any, rowIndex: number, columnIndex: number }) => {
  const field = column.property; // 当前列的字段名
  // 如果当前单元格不为空
  if (row[field] !== null) {
    // 计算rowspan
    let rowspan = 1;
    for (let i = rowIndex + 1; i < tableData.value.length; i++) {
      if (tableData.value[i][field] === null) {
        rowspan++;
      } else {
        break;
      }
    }

    // 计算colspan
    let colspan = 1;
    for (let j = columnIndex + 1; j < Object.keys(row).length; j++) {
      if (row[`fields${j + 1}`] === null) {
        colspan++;
      } else {
        break;
      }
    }

    // 确保其他单元格的合并范围不会超出当前单元格的合并范围  
    // todo--  169行表有问题
    const maxRowspan = getMaxRowspan(rowIndex);
    if (rowspan > maxRowspan) {
      rowspan = maxRowspan;
    }

    // const maxSpan = getMaxSpan(rowIndex, columnIndex);
    // if (rowspan > maxSpan.rowspan) {
    //   rowspan = maxSpan.rowspan;
    // }
    // if (colspan > maxSpan.colspan) {
    //   colspan = maxSpan.colspan;
    // }
    // for (let i = rowIndex + 1; i < rowIndex + rowspan; i++) {
    //   if (tableData.value[i][field] !== null) {
    //     rowspan = i - rowIndex;
    //     break;
    //   }
    // }


    return { rowspan, colspan };
  }
  return { rowspan: 0, colspan: 0 };
}
// 获取当前行序号列的最大合并范围
const getMaxRowspan = (rowIndex: number) => {
  let maxRowspan = 1;
  for (let i = rowIndex + 1; i < tableData.value.length; i++) {
    if (tableData.value[i]['fields1'] === null) {
      maxRowspan++;
    } else {
      break;
    }
  }
  return maxRowspan;
}

// 获取当前表头字段列的最大合并范围
const getMaxSpan = (rowIndex: number, columnIndex: number) => {
  let maxRowspan = 1;
  let maxColspan = 1;

  // 计算最大rowspan
  for (let i = rowIndex + 1; i < tableData.value.length; i++) {
    if (tableData.value[i][`fields${columnIndex + 1}`] === null) {
      maxRowspan++;
    } else {
      break;
    }
  }

  // 计算最大colspan
  for (let j = columnIndex + 1; j < tableColumn.value.length; j++) {
    if (tableData.value[rowIndex][`fields${j + 1}`] === null) {
      maxColspan++;
    } else {
      break;
    }
  }

  return { rowspan: maxRowspan, colspan: maxColspan };
}
loadExcel()

//todo -- 获取接口数据
// const getTableData = async () => {
//   axios.get('./test.json')
//     .then(response => {
//     })
//     .catch(error => {
//     });
// }
</script>

<style scoped></style>